package com.hxh.generater.common.remote;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.hxh.config.ApplicationContextUtil;
import com.hxh.entity.*;
import com.hxh.entity.input.UserInput;
import com.hxh.entity.output.ApiResult;
import com.hxh.entity.po.ClassInfo;
import com.hxh.entity.po.FieldName;
import com.hxh.service.UserService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.List;
import java.util.Map;

@Slf4j
@Data
public class RemoteUtil {
    private static String getUserKey() {
        UserService userService = ApplicationContextUtil.getOneBeanByType(UserService.class);
        List<User> userList = userService.select(new UserInput());
        if (CollectionUtil.isNotEmpty(userList)) {
            User user = userList.get(0);
            String key = user.getKey();
            if (StrUtil.isBlank(key)) {
                throw new RuntimeException("用户未设置远程调用key");
            } else {
                return key;
            }
        } else {
            throw new RuntimeException("请先在user表新增用户");
        }
    }

    /**
     * 去掉classInfo中 ProjectDatasource敏感信息
     *
     * @param params
     */
    private static void removeSensitiveInfo(Map<String, Object> params) {
        Object classInfoObject = params.get("classInfo");
        if (classInfoObject != null) {
            ClassInfo classInfo1 = JSONUtil.toBean(classInfoObject.toString(), ClassInfo.class);
            classInfo1.setProjectDatasource( null);
            List<FieldName> idNameList = classInfo1.getIdNameList();
            if (CollectionUtil.isNotEmpty(idNameList)) {
                for (FieldName fieldName : idNameList) {
                    ProjectTableFiledConfig projectTableFiledConfig = fieldName.getProjectTableFiledConfig();
                    if (projectTableFiledConfig != null) {
                        projectTableFiledConfig.setProjectDatasource(null);
                    }
                }
            }
            List<FieldName> fieldNameList = classInfo1.getFieldNameList();
            if (CollectionUtil.isNotEmpty(fieldNameList)) {
                for (FieldName fieldName : fieldNameList) {
                    ProjectTableFiledConfig projectTableFiledConfig = fieldName.getProjectTableFiledConfig();
                    if (projectTableFiledConfig != null) {
                        projectTableFiledConfig.setProjectDatasource(null);
                    }
                }
            }
            ProjectTablePageConfig projectTablePageConfig = classInfo1.getProjectTablePageConfig();
            if (projectTablePageConfig != null) {
                projectTablePageConfig.setProjectDatasource(null);
            }
            params.put("classInfo", JSONUtil.toJsonStr(classInfo1));
        }
    }

    /**
     * 从远程获取代码
     *
     * @param project
     * @param urlSuffix
     * @param params
     * @return
     */
    public static ApiResult getCodeFromRemote(Project project, String urlSuffix, Map<String, Object> params) {
        removeSensitiveInfo(params);
        String userKey = getUserKey();
        TemplateConfig templateConfig = project.getTemplateConfig();
        String networkUrl = templateConfig.getNetworkUrl();
        if (StringUtils.isBlank(networkUrl)) {
            throw new RuntimeException(templateConfig.getTemplateName() + "的networkUrl为空，请检查配置");
        }
        String url = networkUrl + urlSuffix;
        try (HttpResponse response = HttpUtil.createPost(url)
                .header("key", userKey)
                .form(params)
                .execute()) {
            String post = response.body();
            ApiResult apiResult = JSONUtil.toBean(post, ApiResult.class);
            if (!apiResult.isStatus()) {
                throw new RuntimeException("调用远程接口失败: " + apiResult.getMessage());
            }
            return apiResult;
        } catch (Exception e) {
            log.error("调用远程接口失败: {}", e.getMessage(), e);
            throw new RuntimeException("远程调用失败：" + e.getMessage());
        }
    }

    /**
     * 写入文件
     *
     * @param content
     * @param file
     */
    public static void writeFileToProject(String content, File file) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
            writer.write(content);
        } catch (Exception e) {
            log.error("生成代码成功，写入文件失败!", e);
        }
    }
}
